#include "config_parser.h"

std::string config_get(config_map_t &config_map, const std::string &section, const std::string &option, const std::string fallback)
{
    auto section_iter = config_map.find(section);
    if (section_iter != config_map.end())
    {
        auto option_iter = section_iter->second.find(option);
        if (option_iter != section_iter->second.end())
        {
            return option_iter->second;
        }
    }
    return fallback;
}

config_map_t &config_parse(std::string &file_name)
{
    std::FILE *fp = std::fopen(file_name.c_str(), "r");
    if (fp == nullptr)
    {
        throw std::runtime_error("Failed to open config file:" + std::to_string(__LINE__));
    }
    std::string config_str;
    std::fseek(fp, 0, SEEK_END);
    config_str.resize(std::ftell(fp));
    std::rewind(fp);
    std::fread(&config_str[0], 1, config_str.size(), fp);
    std::fclose(fp);

    static config_map_t config_map;
    std::istringstream iss(config_str);
    std::string current_section = "";

    for (std::string line; std::getline(iss, line);)
    {
        if (line.empty() || line[0] == ';' || line[0] == '#')
        {
            continue;
        }
        else if (line[0] == '[')
        {
            auto pos = line.find(']');
            if (pos != std::string::npos)
            {
                current_section = line.substr(1, pos - 1);
            }
        }
        else if (current_section != "")
        {
            auto pos = line.find('=');
            if (pos != std::string::npos)
            {
                std::string key = line.substr(0, pos);
                std::string value = line.substr(pos + 1);
                key.erase(key.find_last_not_of(" \t\r\n") + 1);
                value.erase(0, value.find_first_not_of(" \t\r\n"));
                value.erase(value.find_last_not_of(" \t\r\n") + 1);
                // if (current_section == section)
                // {
                config_map[current_section][key] = value;
                // }
            }
        }
    }
    return config_map;
}

void free_config_map(config_map_t &config_map)
{
    for (auto &section : config_map)
    {
        section.second.clear();
    }
    config_map.clear();
}
